package com.webkit.web;

import com.lamfire.logger.Logger;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FilterDispatcher implements Filter {
	private static String CHARSET = "utf-8";
	private FilterConfig filterConfig;
	private ApplicationConfiguretion appConfig;
	private Dispatcher dispatcher;
	static final Logger logger = Logger.getLogger(FilterDispatcher.class);

	public void destroy() {
		this.dispatcher = null;
	}

	protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request, HttpServletResponse response, ServletContext context) throws ServletException {
		Dispatcher du = Dispatcher.getInstance();

		if (du == null)
			Dispatcher.setInstance(this.dispatcher);
		else {
			this.dispatcher = du;
		}
		try {
			this.dispatcher.prepare(request, response);
			request = this.dispatcher.wrapRequest(request, getServletContext());
		} catch (IOException e) {
			String message = "Could not wrap servlet request with MultipartRequestWrapper!";
			logger.error(message, e);
			throw new ServletException(message, e);
		}

		return request;
	}

	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		ServletContext context = getServletContext();
		long startTime = System.currentTimeMillis();
		try {
			request = prepareDispatcherAndWrapRequest(request, response, context);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		try {
			this.dispatcher.serviceAction(request, response, context);
		} catch (ClassNotFoundException e) {
			doChain(req, res, chain);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}

		logger.debug("execute's time consuming = " + (System.currentTimeMillis() - startTime));
	}

	private void doChain(ServletRequest req, ServletResponse res, FilterChain chain) {
		try {
			chain.doFilter(req, res);
		} catch (Exception e1) {
			logger.error(e1.getMessage(), e1);
		}
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
		CHARSET = this.filterConfig.getInitParameter("charset");

		this.appConfig = ApplicationConfiguretion.getInstance(ServletUtils.getApplicationClassPathResourceAsStream(filterConfig.getServletContext(), "application.properties"));

		this.dispatcher = new Dispatcher();
		this.dispatcher.setMultipartLimitSize(this.appConfig.getMultipartSizeLimit());
		this.dispatcher.setMultipartSaveDir(this.appConfig.getMultipartTempDir());
		this.dispatcher.setDefaultEncoding(CHARSET);
		this.dispatcher.setActionRoot(this.appConfig.getActionRootPath());
		Dispatcher.setInstance(this.dispatcher);
	}

	public ServletContext getServletContext() {
		return this.filterConfig.getServletContext();
	}
}